#include "Vertex.hpp"

#ifndef __VERTEX_CPP__
#define __VERTEX_CPP__

namespace asteroids
{

template <class T>
Vertex<T>::Vertex()
{
        // Default values
        m_x = m_y = m_z = 0;
}

template <class T>
Vertex<T>::Vertex(T _x, T _y, T _z)
{
        // Set the given values
        m_x = _x;
        m_y = _y;
        m_z = _z; 
}

template <class T>
void Vertex<T>::normalize()
{
        // Normalize the vector
        T mag2 = m_x * m_x + m_y * m_y + m_z * m_z;
		//Ist die Laenge (fast) gleich Null?
        if (fabs(mag2) > TOLERANCE)
        {
				//Ist der Vector schon normalisiert?
				if(fabs(mag2 - 1) > TOLERANCE)
				{
                	T mag = sqrt(mag2);
                	m_x /= mag;
                	m_y /= mag;
                	m_z /= mag;
				}
        }
        else
        {
            throw std::invalid_argument("Invalid argument for normalization");
        }
}

template <class T>
Vertex<T> Vertex<T>::operator+(const Vertex<T> vec) const
{
        // Add value to value
        T tx = m_x + vec.m_x;
        T ty = m_y + vec.m_y;
        T tz = m_z + vec.m_z;
        return Vertex<T>(tx, ty, tz);
}

template <class T>
Vertex<T> Vertex<T>::operator*(T scale) const
{
        // Calculate the result
        T tx = m_x * scale;
        T ty = m_y * scale;
        T tz = m_z * scale;
        return Vertex<T>(tx, ty, tz);
}

template <class T>
T Vertex<T>::operator[](const int &index) const
{
        if(index > 2)
        {
            throw std::out_of_range ("Index out of range!");
        }
        
        // Get the wanted value
        if(index == 0)
        {
                return m_x;
        }

        if(index == 1)
        {
                return m_y;
        }

        if(index == 2)
        {
                return m_z;
        }

        return 0;
}

}

#endif


